home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
aplictns
/
route_10
/
part02
/
board.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-23
|
6KB
|
255 lines
#include <stdio.h>
/*
#ifndef M_XENIX
#include <stdlib.h>
#endif
*/
#include "cell.h"
#define LIMIT 0x10000 /* 64k */
/* board dimensions */
int Nrows = ILLEGAL;
int Ncols = ILLEGAL;
int InitBoardDone = 0; /* sanity check */
/* memory usage */
long Ltotal = 0; /* for board */
long Itotal = 0; /* for dist */
long Ctotal = 0; /* for dir */
/*
** memory is allocated in blocks of rows. as many rows as will fit in 64k are
** allocated in each block. blocks are linked together by pointers. the last
** block has a null 'next' pointer. if you want to route some *really* big
** boards (so big that 640k is not sufficient), you should change the
** algorithms below to test for Lotus-Intel-Microsoft expanded memory (LIM 3.2
** or 4.0) and use it if present. this would be a major enhancement, so if you
** do it i hope you will send it back to me so that it can be incorporated in
** future versions.
*/
struct lmem { /* a block of longs */
struct lmem *next; /* ptr to next block */
long mem[1]; /* more than 1 is actually allocated */
};
struct imem { /* a block of ints */
struct imem *next; /* ptr to next block */
int mem[1]; /* more than 1 is actually allocated */
};
struct cmem { /* a block of chars */
struct cmem *next; /* ptr to next block */
char mem[1]; /* more than 1 is actually allocated */
};
struct lhead { /* header of blocks of longs */
int numrows; /* number of rows per block */
struct lmem *side[2]; /* ptr to first block of each chain */
};
struct ihead { /* header of blocks of ints */
int numrows; /* number of rows per block */
struct imem *side[2]; /* ptr to first block of each chain */
};
struct chead { /* header of blocks of chars */
int numrows; /* number of rows per block */
struct cmem *side[2]; /* ptr to first block of each chain */
};
static struct lhead Board = { 0, {NULL,NULL} }; /* 2-sided board */
static struct ihead Dist = { 0, {NULL,NULL} }; /* path distance to cells */
static struct chead Dir = { 0, {NULL,NULL} }; /* pointers back to source */
extern int justboard;
extern char *Alloc();
void InitBoard();
long GetCell();
void SetCell();
void OrCell();
int GetDist();
void SetDist();
int GetDir();
void SetDir();
void InitBoard () { /* initialize the data structures */
long lx, ly; /* for calculating block sizes */
struct lmem **ltop; /* for building board chain */
struct lmem **lbottom; /* for building board chain */
struct imem **itop; /* for building dist chain */
struct imem **ibottom; /* for building dist chain */
struct cmem **ctop; /* for building dir chain */
struct cmem **cbottom; /* for building dir chain */
int r, c, i, j, k; /* for calculating number of rows per block */
InitBoardDone = 1; /* we have been called */
/* allocate Board (longs) */
for (lx = (long)Ncols*sizeof(long), ly = 0, i = 0;
i < Nrows && ly <= LIMIT - sizeof(long *); ly += lx, i++)
; /* calculate maximum number of rows per block */
Board.numrows = --i;
ltop = &(Board.side[TOP]);
lbottom = &(Board.side[BOTTOM]);
for (j = Nrows; j > 0; j -= i) {
k = (j > i) ? i : j;
ly = ((long)k * lx) + sizeof(long *);
*ltop = (struct lmem *)Alloc( ly );
*lbottom = (struct lmem *)Alloc( ly );
Ltotal += 2*ly;
ltop = (struct lmem **)(*ltop);
lbottom = (struct lmem **)(*lbottom);
}
*ltop = *lbottom = NULL;
if (!justboard) {
/* allocate Dist (ints) */
for (lx = (long)Ncols*sizeof(int), ly = 0, i = 0;
i < Nrows && ly <= LIMIT - sizeof(int *);
ly += lx, i++)
; /* calculate maximum number of rows per block */
Dist.numrows = --i;
itop = &(Dist.side[TOP]);
ibottom = &(Dist.side[BOTTOM]);
for (j = Nrows; j > 0; j -= i) {
k = (j > i) ? i : j;
ly = ((long)k * lx) + sizeof(int *);
*itop = (struct imem *)Alloc( ly );
*ibottom = (struct imem *)Alloc( ly );
Itotal += 2*ly;
itop = (struct imem **)(*itop);
ibottom = (struct imem **)(*ibottom);
}
*itop = *ibottom = NULL;
/* allocate Dir (chars) */
for (lx = (long)Ncols*sizeof(char), ly = 0, i = 0;
i < Nrows && ly <= LIMIT - sizeof(char *);
ly += lx, i++)
; /* calculate maximum number of rows per block */
Dir.numrows = --i;
ctop = &(Dir.side[TOP]);
cbottom = &(Dir.side[BOTTOM]);
for (j = Nrows; j > 0; j -= i) {
k = (j > i) ? i : j;
ly = ((long)k * lx) + sizeof(char *);
*ctop = (struct cmem *)Alloc( ly );
*cbottom = (struct cmem *)Alloc( ly );
Ctotal += 2*ly;
ctop = (struct cmem **)(*ctop);
cbottom = (struct cmem **)(*cbottom);
}
*ctop = *cbottom = NULL;
}
/* initialize everything to empty */
for (r = 0; r < Nrows; r++) {
for (c = 0; c < Ncols; c++) {
SetCell( r, c, TOP, (long)EMPTY );
SetCell( r, c, BOTTOM, (long)EMPTY );
if (!justboard) {
SetDist( r, c, TOP, EMPTY );
SetDist( r, c, BOTTOM, EMPTY );
SetDir( r, c, TOP, EMPTY );
SetDir( r, c, BOTTOM, EMPTY );
}
}
}
}
long GetCell( r, c, s ) /* fetch board cell */
int r, c, s;
{
struct lmem *p;
p = Board.side[s];
while (r >= Board.numrows) {
p = p->next;
r -= Board.numrows;
}
return( p->mem[r*Ncols+c] );
}
void SetCell( r, c, s, x ) /* store board cell */
int r, c, s;
long x;
{
struct lmem *p;
p = Board.side[s];
while (r >= Board.numrows) {
p = p->next;
r -= Board.numrows;
}
p->mem[r*Ncols+c] = x;
}
void OrCell( r, c, s, x ) /* augment board cell */
int r, c, s;
long x;
{
struct lmem *p;
p = Board.side[s];
while (r >= Board.numrows) {
p = p->next;
r -= Board.numrows;
}
p->mem[r*Ncols+c] |= x;
}
int GetDist( r, c, s ) /* fetch distance cell */
int r, c, s;
{
struct imem *p;
p = Dist.side[s];
while (r >= Dist.numrows) {
p = p->next;
r -= Dist.numrows;
}
return( p->mem[r*Ncols+c] );
}
void SetDist( r, c, s, x ) /* store distance cell */
int r, c, s, x;
{
struct imem *p;
p = Dist.side[s];
while (r >= Dist.numrows) {
p = p->next;
r -= Dist.numrows;
}
p->mem[r*Ncols+c] = x;
}
int GetDir( r, c, s ) /* fetch direction cell */
int r, c, s;
{
struct cmem *p;
p = Dir.side[s];
while (r >= Dir.numrows) {
p = p->next;
r -= Dir.numrows;
}
return( (int)(p->mem[r*Ncols+c]) );
}
void SetDir( r, c, s, x ) /* store direction cell */
int r, c, s, x;
{
struct cmem *p;
p = Dir.side[s];
while (r >= Dir.numrows) {
p = p->next;
r -= Dir.numrows;
}
p->mem[r*Ncols+c] = (char)x;
}